package 创建线程第三种方式;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

/**
 * @作者:侯国威
 * @时间: 2020/4/12/14:46
 * @邮箱:1045077189@qq.com 创建线程的方式三：实现Callable接口
 * 继承Callable
 * 相比run()方法，可以有返回值，可以抛出异常；但需要借助FutureTask类
 * Future接口：
 *  1、实现Callable的实现类
 *  2、实现call方法，将此线程须要之兄的操作生命再call中
 *  3、创建Callable接口的实现类对象
 *  4、将此接口作为对象传递到FutureTask()构造器中
 *  5、将FutureTask的对象组为参数传递到Thread类的构造器中实现call（）返回值
 *  6、获取Callable中的call方法的返回值
 *
 *  如何理解Callable接口的方式创建多线程比实现Runanle接口创建多线的强大:
 *  1、call()方法可以抛出异常
 *  2、call()可以有返回值
 *  3、支持泛型返回值
 *
 */
public class Runable {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        //3、创建Callable接口的实现类对象
        Test test = new Test();
        //4、将此接口作为对象传递到FutureTask()构造器中
        FutureTask futureTask = new FutureTask(test);
        //5、将FutureTask的对象组为参数传递到Thread类的构造器中实现call（）返回值
        Thread thread=new Thread(futureTask);
        thread.start();
        //6、获取Callable中的call方法的返回值
        //get()返回值是FutureTask构造器Callable实现类重写的call()的返回值
        Object sum = futureTask.get();
        System.out.println(sum);
    }
}
//1、实现Callable的实现类
class Test implements Callable {
    @Override
    //2、实现call方法，将此线程须要之兄的操作生命再call中
    public Object call() throws Exception {
        int sum = 0;
        for (int i = 0; i < 100; i++) {
            if (i % 2 == 0) {
                sum += i;
                System.out.println(i);//分线程
            }
        }

        return "偶数和:"+sum;//主线程
    }
}
